package cn.ljy.common.model.result;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
 *响应客户端的实体类
 * 约定：如果data为null，则返回空字符串
 *
 *
 *说明：
 * 1.如果是返回成功信息，建议直接调用sucess方法
 * 例如：ResponseData.success(list);
 * 2.如果是返回错误信息，因为状态码较多和错误信息多样化，则建议使用构造函数来做相应操作
 * 例如：new ResponseData<List>(ResultCode.Error)
 */

@Data
@NoArgsConstructor//无参构造
//@AllArgsConstructor//有参构造
@ApiModel(value="服务器响应数据")
public class ResponseData<T> implements Serializable {
    //现在的除了业务的正常失败，其他错误的code都与http状态码一致。
    // 例如登录状态验证失败返回401，没有权限则返回403,500表示未知错误
    @ApiModelProperty(value="状态码，200表示成功，其他状态码说明参照字典。")
    private Integer code;
    @ApiModelProperty(value="业务操作是否成功，true表示成功，判断业务成功还是失败")
    private Boolean success;
    @ApiModelProperty(value="提示信息")
    private String msg;
    @ApiModelProperty(value="返回的数据，如果无返回数据则显示空字符串。")
    private T data;
//为了配合测试比赛，暂时移除
//    @ApiModelProperty(value="请求时间")
//    private Long time;//请求发生时间

    public ResponseData(Integer code,Boolean success,String msg,T data) {
        this.code = code;
        this.success=success;
        this.msg = msg;
//        this.time= LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
        if(data!=null){
            this.data=data;
        }else{
            this.data=(T)new String();
        }
    }


    public ResponseData(Integer code,Boolean success,String msg) {
        this(code,success,msg,null);
    }



    public ResponseData(ResultCode resultCode,Boolean success) {
        this(resultCode.getCode(),success,resultCode.getMsg());
    }

    public ResponseData(ResultCode resultCode,Boolean success,T data) {
        this(resultCode.getCode(),success,resultCode.getMsg(),data);
    }

    /**
     * 供前台直接调用，处理成功的信息。
     * @param data 当成功之后，要传递过去的数据。如果data为null则返回空字符串
     * @return
     */
    public static <V> ResponseData success(V data) {
        return new ResponseData(ResultCode.SUCCESS,true,data);
    }

    /**
     * 供前台直接调用，处理成功的信息。
     * @param data 当成功之后，要传递过去的数据。如果data为null则返回空字符串
     * @param successMsg 成功后的额外数据
     * @return
     */
    public static <V> ResponseData success(String successMsg,V data) {
        return new ResponseData(ResultCode.SUCCESS,true,data);
    }

    /**
     * 供前台直接调用，处理业务处理失败的信息（注意应该是Error类型）。
     * @param errorMsg 当失败之后，要传递过去的错误信息
     * @return
     */
    public static <V> ResponseData error(Integer errorCode,String errorMsg,V data) {
        return new ResponseData(errorCode,false,errorMsg,data);
    }

    /**
     * 供前台直接调用，处理业务处理失败的信息（注意应该是Error类型）。
     * @param errorMsg 当失败之后，要传递过去的错误信息
     * @return
     */
    public static ResponseData error(Integer errorCode,String errorMsg) {
        return ResponseData.error(errorCode,errorMsg,null);
    }


    /**
     * 供前端直接调用，处理业务处理失败的信息，默认为业务错误，即状态码还是200
     * @param errorMsg 当失败之后，要传递过去的错误信息
     * @return
     */
    public static ResponseData error(String errorMsg) {
        return ResponseData.error(ResultCode.ERROR.getCode(),errorMsg);
    }

    /**
     * 供前端直接调用，处理业务处理失败的信息（注意应该是Error类型）。
     * @param errorMsg 当失败之后，要传递过去的错误信息
     * @param data 要传递的错误的数据
     * @return
     */
    public static <V> ResponseData error(String errorMsg,V data) {
        return ResponseData.error(ResultCode.ERROR.getCode(),errorMsg, data);
    }
}
